package com.sencorsta.ids.robot.userSimulation;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.sencorsta.ids.common.proto.ConnectByProto;
import com.sencorsta.ids.core.configure.GlobalConfigure;
import com.sencorsta.ids.core.configure.SysConfig;
import com.sencorsta.ids.core.configure.TypeProtocol;
import com.sencorsta.ids.core.configure.TypeSerialize;
import com.sencorsta.ids.core.log.Out;
import com.sencorsta.ids.core.tcp.opensocket.OpenMessage;
import com.sencorsta.ids.core.tcp.opensocket.client.SimulationUser;
import com.sencorsta.ids.robot.proto.*;
import com.sencorsta.ids.robot.util.RedPackageInfo;
import com.sencorsta.ids.robot.util.RoomInfo;
import com.sencorsta.utils.net.HttpRequester;
import com.sencorsta.utils.net.HttpRespons;
import com.sencorsta.utils.string.StringUtil;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Random;


import static com.sencorsta.ids.robot.userSimulation.SimulationCenter.SEND_INTERVAL;
import static com.sencorsta.ids.robot.util.PushAndSaved.protpToByte;

public class GameSimUser extends SimulationUser {

    public boolean isOnline;//是否连接成功
    public boolean isActive;//是否启用
    public boolean isInRoom;//加入房间标识
    public int heartCount;//连接心跳
    public int zeroCount;//游戏服连接心跳
    public int loginCount;//游戏服连接心跳
    public String phone;//手机
    public String password;
    public String token;


    public int gameId;//加入游戏的Id
    public int roomId;//加入房间的Id

    public long sMinAmount;//机器人发包最小金额
    public long sMaxAmount;//机器人发包最大金额

    //监听回调/推送消息集中处理中心
    @Override
    public void onMessage(OpenMessage msg) {

        switch (msg.method) {
            case "ConnectByProto.C"://连接服务器回调
                backConnect(msg);
                break;
            case "JoinRoom.C"://加入房间回调
                joinRoomCB(msg);
                break;
            case "LeaveRoom.C"://离开房间回调
                leaveRoomCB(msg);
                break;
            case "push.RedPackage"://玩家发红包的推送监听
                monitorPushRedPackage(msg);
                break;
            case "RobAllRedPackage.C"://抢红包回调
                robAllRedPackageCB(msg);
                break;
            case "push.RobMoney"://机器人抢到的钱回调
                pushRobMoney(msg);
                break;
            case "SendSaoLei.C"://发扫雷包回调
                sendSaoLeiCB(msg);
                break;
            case "SendNiuNiu.C"://发扫雷包回调
                sendNiuNiuCB(msg);
                break;
            case "push.RedPackageResult"://红包结算监听
                RedPackageResult(msg);
                break;
            case "zero.C":
                backZero(msg);
                break;

        }
    }


    @Override
    public void onStarted() {
        isOnline = false;
        heartCount = 300;
        zeroCount = 0;
        loginCount = 0;
        isActive = false;
        isInRoom = false;
        //login();
    }

    @Override
    public void onUpdate() {
        if (isActive) {
            if (isOnline == true) {
                heartCount++;
                zeroCount++;
                if (heartCount >= 300) {
                    sendHeart();
                    heartCount = 0;
                }
                if (zeroCount >= 60) {
                    Out.warn(userId + "游戏服掉线");
                    isOnline = false;
                    channel.close();
                    zeroCount = 0;
                }
                if (zeroCount == 20) {
                    sendZero();
                }
            } else {
                //register();
                loginCount++;
                if (loginCount > 30) {
                    loginCount = 0;
                    login();
                }
            }
        }
    }

    @Override
    public void onRemoved() {
        Out.info("机器人掉线:" + userId);
        isOnline = false;
        SimulationCenter.activateSimulationUserMap.remove(userId);
    }

    //登入
    public void login() {
        JSONObject resJ = loginToken();
        if (resJ==null){
            Out.warn("机器人登录请求失败！");
            return;
        }
        if (resJ.getIntValue("code") == 0) {
            JSONObject result = resJ.getJSONObject("data");
            String serverIp = result.getString("host");
            int port = result.getIntValue("port");
            token = result.getString("token");
            channel = SimulationCenter.openClientBootstrap.connect(this.userId, serverIp, port);
            channel.attr(GlobalConfigure.__KEY_SIMULATIONUSER).set(this);
            sendConnect(result.getString("token"));
        } else {
            Out.warn("机器人登录信息失败！"+resJ);
        }

    }

    public JSONObject loginToken() {
        if (StringUtil.isNotEmpty(token)) {
            JSONObject json = new JSONObject();
            json.put("token", URLEncoder.encode(token, Charset.forName("UTF-8")));
            HttpRequester req = new HttpRequester();
            HttpRespons res = null;
            try {
                res = req.sendPost(SysConfig.getInstance().get("Gateway.TokenVerify"), json);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            JSONObject resJ = JSON.parseObject(res.getContent());
            if (resJ.getIntValue("code") == 0) {
                return resJ;
            } else {
                token=null;
                return loginPassWord();
            }
        }else {
            return loginPassWord();
        }
    }

    public JSONObject loginPassWord() {
        JSONObject json = new JSONObject();
        json.put("phone", phone);
        json.put("password", password);
        HttpRequester req = new HttpRequester();
        HttpRespons res = null;
        try {
            res = req.sendPost(SysConfig.getInstance().get("Gateway.LoginPhone"), json);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        JSONObject resJ = JSON.parseObject(res.getContent());
        return resJ;
    }

////////////////////////////////连接socket--开始///////////////////////////////////

    //连接socket
    public void sendConnect(String token) {
        ConnectByProto.ConnectByProtoReq.Builder req = ConnectByProto.ConnectByProtoReq.newBuilder();
        req.setToken(token);
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "proxy.ConnectByProto";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //连接socket的回调
    public void backConnect(OpenMessage msg) {
        try {
            ConnectByProto.ConnectByProtoRes res = ConnectByProto.ConnectByProtoRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
//                Random random = new Random();
//                int gameId = random.nextInt(6) + 1;
//                int roomId = getRoomList(gameId);
//                joinRoom(gameId, roomId);
//                joinRoom(6, 13);
                if (isInRoom) {
                    joinRoom(gameId, roomId);
                } else {
                    isOnline = true;
                }
            } else {
                Out.warn("机器人链接失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

////////////////////////////////连接socket--开始///////////////////////////////////

    //加入房间
    public void joinRoom(int gameId, int roomId) {
        GameJoinRoomByProto.JoinRoomReq.Builder req = GameJoinRoomByProto.JoinRoomReq.newBuilder();
        req.setGameId(gameId);
        req.setRoomId(roomId);
        this.gameId = gameId;
        this.roomId = roomId;
        Out.debug(gameId, "------加入房间成功------", roomId);
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.JoinRoom";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //加入房间的回调
    public void joinRoomCB(OpenMessage msg) {
        try {
            GameJoinRoomByProto.JoinRoomRes res = GameJoinRoomByProto.JoinRoomRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                isInRoom = true;
                isOnline = true;
                long sMax = res.getSMaxAmount();
                long sMin = res.getSMinAmount();
                if (sMax == 0) {//防止管理人员没设置瞎几把发*---设置一个默认值--机器人抢包金额大小
                    sMax = 5000;
                }
                if (sMin == 0) {
                    sMin = 500;
                }


                this.sMaxAmount = sMax;
                this.sMinAmount = sMin;
                SimulationCenter.activateSimulationUserMap.put(userId, this);
                long time = new Random().nextInt(SEND_INTERVAL * 1000);
                RoomInfo roomInfo = new RoomInfo(gameId, roomId, time);
                SimulationCenter.roomInfo.put(gameId + roomId + "", roomInfo);
                Out.info(userId, " 进入房间成功==>", roomId, "----------", gameId, "==sMin==>", sMin, "--sMax-->", sMax);
            } else {
                Out.warn("进入房间失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //离开房间
    public void leaveRoom() {
        isInRoom = false;//离开房间标识
        this.roomId = 0;
        this.gameId = 0;
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.LeaveRoom";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        sendMsg(msg);
    }


    //离开房间回调
    public void leaveRoomCB(OpenMessage msg) {
        try {
            GameLeaveRoomByProto.LeaveRoomRes res = GameLeaveRoomByProto.LeaveRoomRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                Out.error("离开成功.......");
                SimulationCenter.activateSimulationUserMap.remove(userId);
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //获取随机游戏随机房间
    public int getRoomList(int gameId) {
        Random random = new Random();
        HttpRequester req = new HttpRequester();
        JSONObject json = new JSONObject();
        json.put("gameId", gameId);
        try {
            HttpRespons res = req.sendPost(SysConfig.getInstance().get("Game.GetRoomInfoList"), json);
            JSONObject resJ = JSON.parseObject(res.getContent());
            if (resJ.getIntValue("code") == 0) {
                JSONObject JB = resJ.getJSONObject("data");
                int size = JB.getJSONArray("roomIdList").size();
                if (size == 0) {
                    return -1;
                }
                return JB.getJSONArray("roomIdList").getJSONObject(random.nextInt(size)).getInteger("roomId");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }
////////////////////////////////房间操作--结束///////////////////////////////////

////////////////////////////////包操作--开始///////////////////////////////////

    //监听发包推送
    public void monitorPushRedPackage(OpenMessage msg) {
        try {
            Out.debug("--------------监听发包推送---monitorPushRedPackage--------------");
            GamePushRedPackageByProto.PushRedPackage push = GamePushRedPackageByProto.PushRedPackage.parseFrom(msg.data);
            if (SimulationCenter.IS_ROB) {
                long time = new Random().nextInt(SimulationCenter.ROB_INTERVAL * 1000);
                RedPackageInfo rp = new RedPackageInfo(push.getGameId(), push.getRoomId(), push.getRpId(), time);
                SimulationCenter.redPackage.put(push.getRpId(), rp);
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

    }

    //模拟用户开始抢包
    public void simulationUserRob(int gameId, int roomId, String rpId) {
        Out.debug("开始抢包：", gameId, " ", roomId, " ", rpId);
        GameRobAllByProto.RobAllReq.Builder req = GameRobAllByProto.RobAllReq.newBuilder();
        req.setGameId(gameId);
        req.setRoomId(roomId);
        req.setRpId(rpId);
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.RobAllRedPackage";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //抢包回调
    public void robAllRedPackageCB(OpenMessage msg) {
        Out.debug("--------------------抢包回调------robAllRedPackageCB--------------------------");
        try {
            GameRobAllByProto.RobAllRes res = GameRobAllByProto.RobAllRes.parseFrom(msg.data);
            if (res.getMsg().getCode() != 0) {
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //抢到的钱推送监听
    public void pushRobMoney(OpenMessage msg) {
        Out.debug("--------------------抢到的钱推送监听------pushRobMoney--------------------------");
        try {
            GamePushRobMoneyByProto.PushRobMoney push = GamePushRobMoneyByProto.PushRobMoney.parseFrom(msg.data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //结算监听
    public void RedPackageResult(OpenMessage msg) {
        try {
            Out.debug("--------------结算监听-----------------");
            GamePushRedPackageByProto.PushRedPackage push = GamePushRedPackageByProto.PushRedPackage.parseFrom(msg.data);

            if (SimulationCenter.redPackage.containsKey(push.getRpId())) {
                SimulationCenter.redPackage.get(push.getRpId()).unUsed = true;
            }

        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }


    //机器人发扫雷红包
    public void sendSaoLei() {
        Out.debug("------------模拟用户开始发包---机器人发扫雷红包-----------");
        GameSendSaoLeiByProto.SendSaoLeiReq.Builder req = GameSendSaoLeiByProto.SendSaoLeiReq.newBuilder();
        req.setCount(7);
        req.setGameId(gameId);
        req.setRoomId(roomId);
        long sendAMount = SimulationCenter.sRandomAmount(sMinAmount, sMaxAmount);
        Out.debug("sendAMount------------->", sendAMount);
        req.setSendAmount(sendAMount);

        req.setThunderNumber(SimulationCenter.randomOneThunderNumber());
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.SendSaoLei";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //机器人发扫雷红包回调
    public void sendSaoLeiCB(OpenMessage msg) {
        Out.debug("--------------机器人发扫雷红包回调---SendSaoLeiCB--------------");
        try {
            GameSendSaoLeiByProto.SendSaoLeiRes res = GameSendSaoLeiByProto.SendSaoLeiRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                Out.debug("发扫雷红包成功");
            } else {
                Out.warn("发扫雷红包失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //机器人发牛牛红包
    public void sendNiuNiu() {
        Out.debug("------------模拟用户开始发包---机器人发牛牛红包-----------");
        GameSendNiuNiuByProto.SendNiuNiuReq.Builder req = GameSendNiuNiuByProto.SendNiuNiuReq.newBuilder();
        req.setCount(SimulationCenter.randomCount(5));
        req.setGameId(gameId);
        req.setRoomId(roomId);
        long sendAMount = SimulationCenter.sRandomAmount(sMinAmount, sMaxAmount);
        Out.debug("sendAMount------------->", sendAMount);
        req.setSendAmount(sendAMount);

        //req.setSendAmount(SimulationCenter.sRandomAmount(sMinAmount,sMaxAmount));
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.SendNiuNiu";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //机器人发牛牛红包回调
    public void sendNiuNiuCB(OpenMessage msg) {
        Out.debug("--------------机器人发牛牛红包回调---sendNiuNiuCB--------------");
        try {
            GameSendSaoLeiByProto.SendSaoLeiRes res = GameSendSaoLeiByProto.SendSaoLeiRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                Out.debug("牛牛红包成功");
            } else {
                Out.warn("牛牛红包失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //初始化包大小
    public static final int[] packageCount = new int[]{5, 6, 7, 9, 10};

    //机器人发禁抢玩法的包
    public void sendJinQiang() {
        Out.debug("------------模拟用户开始发包---机器人发禁抢玩法的包----sendJinQiang-------");
        GameSendJinQiangByProto.SendJinQiangReq.Builder req = GameSendJinQiangByProto.SendJinQiangReq.newBuilder();
        req.setGameId(gameId);
        req.setRoomId(roomId);
        long sendAMount = SimulationCenter.sRandomAmount(sMinAmount, sMaxAmount);
        Out.debug("sendAMount------------->", sendAMount);
        req.setSendAmount(sendAMount);

        //req.setSendAmount(SimulationCenter.sRandomAmount(sMinAmount,sMaxAmount));

        int count = packageCount[SimulationCenter.randomAssign(0, 5)];
        int redType = 0;
        if (SimulationCenter.randomProbability() > 95 && count == 6) {
            redType = 666;
        }
        List<Integer> thunderNumberList = SimulationCenter.randomMoreThunderNumber(count, redType);
        req.setCount(count);
        req.setRedType(redType);
        req.addAllThunderNumber(thunderNumberList);

        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.SendJinQiang";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }


    //机器人发禁抢玩法的包回调
    public void sendJinQiangCB(OpenMessage msg) {
        try {
            GameSendJinQiangByProto.SendJinQiangRes res = GameSendJinQiangByProto.SendJinQiangRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                Out.debug("禁抢红包成功");
            } else {
                Out.warn("禁抢红包失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //机器人发龙虎玩法的包
    public void sendLongHu() {
        Out.debug("------------模拟用户开始发包---机器人发龙虎玩法的包----sendLongHu-------");
        GameSendLongHuByProto.SendLongHuReq.Builder req = GameSendLongHuByProto.SendLongHuReq.newBuilder();
        req.setGameId(gameId);
        req.setRoomId(roomId);
        long sendAMount = SimulationCenter.sRandomAmount(sMinAmount, sMaxAmount);
        Out.debug("sendAMount------------->", sendAMount);
        req.setSendAmount(sendAMount);
        //req.setSendAmount(SimulationCenter.sRandomAmount(sMinAmount,sMaxAmount));
        req.setCount(SimulationCenter.randomCount(5));
        int detain = 1;
        if (SimulationCenter.randomProbability() > 50) {
            detain = 2;
        }
        req.setDetain(detain);

        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.SendLongHu";
        msg.serializeType = TypeSerialize.TYPE_PROTOBUF;
        byte[] bytes = protpToByte(req);
        msg.data = bytes;
        sendMsg(msg);
    }

    //机器人发龙虎玩法的包回调
    public void sendLongHuCB(OpenMessage msg) {
        Out.debug("--------------机器人发龙虎玩法的包回调---sendLongHuCB--------------");
        try {
            GameSendLongHuByProto.SendLongHuRes res = GameSendLongHuByProto.SendLongHuRes.parseFrom(msg.data);
            if (res.getMsg().getCode() == 0) {
                Out.debug("龙虎红包成功");
            } else {
                Out.warn("龙虎红包失败！");
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    //机器人发包总和
    public void sendPackageAll() {
        Out.debug("开始发包", gameId);
        switch (gameId) {
            case 1:
                sendSaoLei();
                break;
            case 2:
                sendNiuNiu();
                break;
            case 3:
                sendJinQiang();
                break;
            case 4:
                sendLongHu();
                break;
        }
    }

////////////////////////////////包操作--结束///////////////////////////////////

    //注册
    public void register() {

        JSONObject jsonRegisterPhone = new JSONObject();
        jsonRegisterPhone.put("password", "888888");
        jsonRegisterPhone.put("code", "888888");
        jsonRegisterPhone.put("SecondaryPassword", "888888");
        jsonRegisterPhone.put("phone", phone);

        HttpRequester req = new HttpRequester();

        HttpRespons res = null;
        try {
            //res = req.sendPost("http://103.100.140.99:9020/Gateway/RegisterPhone", jsonRegisterPhone);
            res = req.sendPost("http://127.0.0.1:9020/Gateway/RegisterPhone", jsonRegisterPhone);
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject resJ = JSON.parseObject(res.getContent());
        if (resJ.getIntValue("code") == 0) {
            login();
        } else {
            Out.debug("注册失败！！！");
        }
    }

    public void loginOut() {
        if (isInRoom) {
            leaveRoom();
        }
        channel.close();
        onStarted();
    }


    public void sendZero() {
        OpenMessage msg = new OpenMessage();
        msg.header.type = TypeProtocol.TYPE_REQ;
        msg.method = "game.zero";
        msg.serializeType = TypeSerialize.TYPE_STRING;
        byte[] bytes = "0".getBytes();
        msg.data = bytes;
        sendMsg(msg);
    }

    //连接socket的回调
    public void backZero(OpenMessage msg) {
        Out.debug("backZero:" + new String(msg.data));
        if (isInRoom == true && !new String(msg.data).equals("0")) {
            isOnline = false;
            channel.close();
        }
        zeroCount = 0;
    }
}
